package com.example.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.Exception.InvalidOpenidException;
import com.example.Utils.GetOpenIdUtil;
import com.example.Utils.JwtUtils;
import com.example.Utils.LoggerUtils;
import com.example.model.User;
import com.example.dao.UserMapper;
import com.example.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Hello
 * @since 2024-07-03
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    private static final Logger logger = LoggerUtils.getLogger(UserServiceImpl.class);
    @Autowired
    UserMapper userMapper;
    @Value("${weixin.appid}")
    private String appid;

    @Value("${weixin.secret}")
    private String secret;

    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    private JwtUtils jwtUtils;
    @Override
    public String login(String code) {
        String session = GetOpenIdUtil.getopenid(appid,code,secret);
        logger.info("code获取内容"+session);
        JSONObject jsonObject = JSONUtil.parseObj(session);
        String openid = jsonObject.getStr("openid");
        String sessionKey = jsonObject.getStr("session_key");
        logger.info("openid:{},session_key:{}",openid,sessionKey);

        String token = jwtUtils.generateToken(openid,sessionKey);
        logger.info("token:{}",token);
        User user;
        if(!isRegister(openid)) {
            user = Register(openid);
        } else {
            user = getInfo(openid);
        }
        //用户信息存到redis中
        User userCopy = BeanUtil.copyProperties(user, User.class);
        //这里将userCopy中的属性转为string类型的
        Map<String, Object> userMap = BeanUtil.beanToMap(userCopy,new HashMap<>(),
                CopyOptions.create().setIgnoreNullValue(true)
                        .setFieldValueEditor((fieldName,fieldValue)->fieldValue.toString())
        );

        //将用户信息放到redis中
        stringRedisTemplate.opsForHash().putAll(token,userMap);
        //设置有效期
        stringRedisTemplate.expire(token,10, TimeUnit.MINUTES);
        //redis获取用户信息
        Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(token);
        User userDTO = BeanUtil.fillBeanWithMap(map, new User(), false);
        logger.info("用Redis里的user信息，新建的user副本，这个副本的openid：{}",userDTO.getWechatOpenid());

        return token;
    }
    //注册接口
    @Override
    public User Register(String openid) {
        if(openid == null){
            throw new InvalidOpenidException("OpenID cannot be null");
        }
        User user = new User();
        user.setWechatOpenid(openid);
        user.setWechatUnionid(openid);
        return userMapper.insert(user) == 1 ? user : null;
    }
    //判断是否注册
    @Override
    public Boolean isRegister(String openid) {
        QueryWrapper<User> user = new QueryWrapper();
        user.eq("wechat_OpenID",openid);
        User user1 = userMapper.selectOne(user);
        return user1 != null;
    }
    //获取用户信息
    @Override
    public User getInfo(String openid) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper();
        userQueryWrapper.eq("wechat_OpenID",openid);
        User user = userMapper.selectOne(userQueryWrapper);
        return user;
    }
    //对用户信息进行更新
    @Override
    public Boolean updateUser(String openid,User user) {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        logger.info("saveUser中wechat_OpenID:{}",openid);
        String avatar = user.getWechatAvatar();
        String nickname = user.getWechatNickname();
        if(!avatar.equals("null")) {
            updateWrapper.eq("wechat_OpenID",openid).set("wechat_avatar",user.getWechatAvatar());
        }
        if(!nickname.equals("null")) {
            updateWrapper.eq("wechat_OpenID",openid).set("wechat_nickname",user.getWechatNickname());
        }

        if(userMapper.update(null, updateWrapper) != 1) {
            logger.info("update失败");
            return false;
        }
        logger.info("update成功");
        return true;
    }

    public Integer getPoints(User user){
        return user.getUserPoints();
    }
}
